/**
 *
 * Copyright (C) 2007 iPhone Dev Team  
 *
 *    Unlock Authors: Daeken, gray, iZsh, Sam
 *    UI Development: Erica, kroo, darkten
 *	  RCE: roxfan, daeken, darkmen, gray, iZsh, Sam  
 *    Coop: pytey, uns, zappaz, Zf, guest184, leachbj
 *	  Art: Wheat, darkten
 *
 *    Paypal donation and contact -> iphone.devteam@gmail.com
 *
 *	  For further information check http://www.hackint0sh.org
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

/* Old header:

  Copyright 2007 Daeken && iZsh
 
  No iPhones were harm and no money wasted in the process...
  Credits: Daeken, iZsh, roxfan and an Anonymous contributor

  All code, information or data [from now on "data"] available
  from the "iPhone dev team" [1] or any other project linked from
  this or other pages is owned by the creator who created the data.
  The copyright, license right, distribution right and any other
  rights lies with the creator.

  It is prohibitied to use the data without the written agreement
  of the creator. This included using ideas in other projects
  (commercial or not commercial).

  Where data was created by more than 1 creator a written agreement
  from each of the creators has to be obtained.

  Punishment: Monkeys coming out of your ass Bruce Almighty style.

  [1] http://iphone.fiveforty.net/wiki/index.php?title=Main_Page
*/
#ifndef __PACKETS_H__
#define __PACKETS_H__

#pragma pack(1)

enum OPCODE
{
  BBSETBAUDRATE = 0x82,
  BBCFISTAGE1 = 0x84,
  BBCFISTAGE2 = 0x85,
  BB102 = 0x102,
  BBBEGINSECPACK = 0x204,
  BBENDSECPACK = 0x205,
  BBGETFLASHID = 0x801,
  BBSEEK = 0x802,
  BBREAD = 0x803,
  BBWRITE = 0x804,
  BBERASE = 0x805,
  BBERASESTATUS = 0x806,
  BBNOP1 = 0x807,
  BBWRITEPAGE = 0x808,
  BBNOP2 = 0x809,
};

typedef struct {
  unsigned char opcode; // 0x0b
  unsigned int bootmode;
  unsigned int major;
  unsigned int minor;
  char version[0x33];
} VersionAck;

typedef struct {
  unsigned short int cls;
  unsigned short int opcode;
  unsigned short int param_len;
} CmdHeader;

// Baudrate
typedef struct {
  CmdHeader cmd;
  unsigned int baud;
  unsigned int checksum;
} BaudReq;

// CFIStage
typedef struct {
  CmdHeader cmd;
  unsigned int checksum;
} CFIStage1Req;

typedef struct {
  CmdHeader cmd;
  unsigned char data[0x100];
  unsigned int checksum;
} CFIStage1Ack;

// Secpack

typedef struct {
  CmdHeader cmd;
  unsigned char data[0x800];
  unsigned int checksum;
} BeginSecpackReq;

typedef struct {
  CmdHeader cmd;
  unsigned short unknown1;
  unsigned int unknown2;
  unsigned int checksum;
} BeginSecpackAck;

typedef struct {
  CmdHeader cmd;
  unsigned short unknown;
  unsigned int checksum;
} EndSecpackReq;

typedef struct {
  CmdHeader cmd;
  unsigned short unknown;
  unsigned int checksum;
} EndSecpackAck;

// FlashID
typedef struct {
  CmdHeader cmd;
  unsigned int checksum;
} GetFlashIDReq;

typedef struct {
  CmdHeader cmd;
  unsigned int null;
  unsigned int major;
  unsigned int minor;
  char string[8];
  unsigned int checksum;
} GetFlashIDAck;

// Seek
// The addr seems to be checked against a white list
typedef struct {
  CmdHeader cmd;
  unsigned int addr; // Virtual Address to map from
  unsigned int checksum;
} SeekReq;

typedef struct {
  CmdHeader cmd;
  unsigned short unkown1;
  unsigned int unnown2;
  unsigned int checksum;
} SeekAck;

// Read
typedef struct {
  CmdHeader cmd;
  unsigned short int size;
  unsigned int checksum;
} ReadReq;

typedef struct {
  CmdHeader cmd;
  unsigned char first_char;
} ReadAck;

// Write
// Don't forget the checksum at the end of the buffer
// "Write one page" is a wrapper around Write to write one page (0x800 byte)
typedef struct {
  CmdHeader cmd;
  unsigned char first_char;
} WriteReq;

typedef struct {
  CmdHeader cmd;
  unsigned short int unknown; // seems to be xor of the bytes written or something close to it
  unsigned int checksum;
} WriteAck;

// Erase
// This command seems to have a backdoor:
// if low_addr == 0xA03D0000 then size is hardcoded to 0x20000
// else if low_addr == 0xA07D0000 then size is hardcoded to 0x22000
// What is interesting is that because the NOR is 4M long:
// 0xA07D0000 - 4M == 0xA03D0000
// so... same address, one fold cycled, and erase an extra 0x2000
// mmm... factory reset? Who want to risk his phone? (assuming you
// can go around the secpack)
// Also from the NOR dump, it looks like this range (0xA03D0000 -> 0xA03F2000) is
// hidden by the read command (would need to disassemble the low level
// read command to be sure)
typedef struct {
  CmdHeader cmd;
  unsigned int low_addr;
  unsigned int high_addr;
  unsigned int checksum;
} EraseReq;

typedef struct {
  CmdHeader cmd;
  unsigned short unknown1;
  unsigned int checksum;
} EraseAck;

// Erase status query
// Take the EraseAck and just change the opcode
typedef struct {
  CmdHeader cmd;
  unsigned short int unknown1;
  unsigned int checksum;
} EraseStatusReq;

// Operation performed when done == 1; loop until you get it
typedef struct {
  CmdHeader cmd;
  unsigned char done;
  unsigned int unknown2; // looks like a VA addr
  unsigned char unknown3;
  unsigned int checksum;
} EraseStatusAck;

#endif
